package epidemic

import (
	"errors"
	"fmt"
	"gitee.com/baal1990/epidemic/global"
	"gitee.com/baal1990/epidemic/model/common/request"
	"gitee.com/baal1990/epidemic/model/epidemic"
	epidemicReq "gitee.com/baal1990/epidemic/model/epidemic/request"
	"gitee.com/baal1990/epidemic/utils/msgsms"
	"gitee.com/baal1990/epidemic/utils/prepare"
	"github.com/xuri/excelize/v2"
	"strconv"
	"strings"
	"time"
)

type EpidemicUserService struct {
}

// CreateEpidemicUser 创建EpidemicUser记录
// Author [piexlmax](https://github.com/piexlmax)
func (epidemicUserService *EpidemicUserService) CreateEpidemicUser(epidemicUser epidemic.EpidemicUser) (err error) {
	if epidemicUser.Status == "" {
		epidemicUser.Status = "1"
	}
	tx := global.GVA_DB.Begin()
	// 先查看是否有预设用户，有就直接覆盖，使用管理员设置的
	userTmp := epidemic.EpidemicUser{}
	if err = tx.Where("mobile=?", epidemicUser.Mobile).Find(&userTmp).Error; err != nil {
		return
	}
	if userTmp.ID != 0 && userTmp.Name == "" {
		if err = tx.Where("mobile=?", epidemicUser.Mobile).Delete(&epidemic.EpidemicUser{}).Error; err != nil {
			return
		}
	}
	if err = tx.Create(&epidemicUser).Error; err != nil {
		tx.Rollback()
		return
	}
	tx.Commit()
	return nil
}

// DeleteEpidemicUser 删除EpidemicUser记录
// Author [piexlmax](https://github.com/piexlmax)
func (epidemicUserService *EpidemicUserService) DeleteEpidemicUser(id string) (err error) {
	user := &epidemic.EpidemicUser{}
	err = global.GVA_DB.Where("id = ?", id).First(&user).Error
	if err != nil {
		return err
	}
	db := global.GVA_DB
	err = db.Where("id=?", id).Delete(user).Error
	if err != nil {
		return err
	}
	// 物理删除
	err = db.Unscoped().Where("mobile=?", user.Mobile).Delete(&epidemic.EpidemicRelatedStaff{}).Error
	if err != nil {
		return err
	}
	err = db.Where("mobile=?", user.Mobile).Delete(&epidemic.EpidemicInvestigationDetails{}).Error
	if err != nil {
		return err
	}
	return err
}

// DeleteEpidemicUserByIds 批量删除EpidemicUser记录
// Author [piexlmax](https://github.com/piexlmax)
func (epidemicUserService *EpidemicUserService) DeleteEpidemicUserByIds(ids request.IdsReq) (err error) {
	err = global.GVA_DB.Delete(&[]epidemic.EpidemicUser{}, "id in ?", ids.Ids).Error
	return err
}

// UpdateEpidemicUser 更新EpidemicUser记录
// Author [piexlmax](https://github.com/piexlmax)
func (epidemicUserService *EpidemicUserService) UpdateEpidemicUser(epidemicUser epidemic.EpidemicUser) (err error) {
	// 生日字段可能不识别，强制转一下
	if len(epidemicUser.BirthDate) >= 10 {
		epidemicUser.BirthDate = epidemicUser.BirthDate[:10]
	}
	tx := global.GVA_DB.Begin()
	userTmp := epidemic.EpidemicUser{}
	if err = tx.Where("mobile=?", epidemicUser.Mobile).Find(&userTmp).Error; err != nil {
		return
	}
	if userTmp.ID != 0 && userTmp.Name == "" {
		if err = tx.Where("mobile=?", epidemicUser.Mobile).Delete(&epidemic.EpidemicUser{}).Error; err != nil {
			return
		}
	}
	if err = tx.Where("id=?", epidemicUser.ID).Select("*").Updates(&epidemicUser).Error; err != nil {
		tx.Rollback()
		return
	}
	tx.Commit()
	return err
}

// UpdateEpidemicUserMobile 更新EpidemicUser记录
// Author [piexlmax](https://github.com/piexlmax)
func (epidemicUserService *EpidemicUserService) UpdateEpidemicUserMobile(epidemicUser epidemic.EpidemicUser) (err error) {
	db := global.GVA_DB
	if err = db.Where("mobile=?", epidemicUser.Mobile).Select("*").Updates(&epidemicUser).Error; err != nil {
		return
	}
	return err
}

// GetEpidemicUser 根据id获取EpidemicUser记录
// Author [piexlmax](https://github.com/piexlmax)
func (epidemicUserService *EpidemicUserService) GetEpidemicUser(id int) (epidemicUser epidemic.EpidemicUser, err error) {
	err = global.GVA_DB.Where("id = ? and AES_DECRYPT(FROM_BASE64(`name`), '"+global.ENCRYPTKEY_AES+"') !=''", id).First(&epidemicUser).Error
	if err != nil {
		return
	}
	// 处理加密字段
	epidemicUser, err = encryptUserInfo(epidemicUser)
	if err != nil {
		return
	}
	return
}

/*
*
获取用户，不关心审核状态
*/
func (epidemicUserService *EpidemicUserService) GetEpidemicUserAny(id int) (epidemicUser epidemic.EpidemicUser, err error) {
	//查询审批通过的用户
	err = global.GVA_DB.Where("id = ?", id).First(&epidemicUser).Error
	return
}

/*
*
获取可用用户
*/
func (epidemicUserService *EpidemicUserService) GetEpidemicUserEnable(id int) (epidemicUser epidemic.EpidemicUser, err error) {
	//查询审批通过的用户
	err = global.GVA_DB.Where("id = ? and status=2", id).First(&epidemicUser).Error
	return
}

// GetEpidemicUserInfoList 分页获取EpidemicUser记录
// Author [piexlmax](https://github.com/piexlmax)
func (epidemicUserService *EpidemicUserService) GetEpidemicUserInfoList(info epidemicReq.EpidemicUserSearch, user epidemic.EpidemicUser) (list []epidemic.EpidemicUser, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&epidemic.EpidemicUser{}).Where(" AES_DECRYPT(FROM_BASE64(`name`), '" + global.ENCRYPTKEY_AES + "') != ''") // 屏蔽自动注册产生的用户
	if user.Role != global.DICT_ROLES_SUPER {
		db = db.Where("company=? and department in ?", user.Company, prepare.Department(user.Department))
	}
	var epidemicUsers []epidemic.EpidemicUser
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.EpidemicUserSearch.Name != "" {
		db = db.Where(" AES_DECRYPT(FROM_BASE64(`name`), '"+global.ENCRYPTKEY_AES+"') like ?", "%"+info.Name+"%")
	}
	if info.EpidemicUserSearch.Department != "" {
		db = db.Where("department = ?", info.Department)
	}
	if info.EpidemicUserSearch.Location != "" {
		db = db.Where("location = ?", info.Location)
	}
	if info.EpidemicUserSearch.Status != "" {
		db = db.Where("status = ?", info.Status)
	}
	if info.EpidemicUserSearch.Role != "" {
		db = db.Where("role = ?", info.Role)
	}
	if info.EpidemicUserSearch.Label != "" {
		labelSlice := strings.Split(info.EpidemicUserSearch.Label, ",")
		for i, e := range labelSlice {
			if i == 0 {
				db = db.Where("label like ?", "%"+e+"%")
			} else {
				db = db.Or("label like ?", "%"+e+"%")
			}
		}
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).Offset(offset).Order("id desc").Find(&epidemicUsers).Error
	if err != nil {
		return nil, 0, err
	}
	err = encryptUserInfoInList(epidemicUsers)
	return epidemicUsers, total, err
}

// 对用户的name、mobile、residentialAddressCode、residentialAddressDetail进行rsa加密
func encryptUserInfoInList(users []epidemic.EpidemicUser) (err error) {
	for i, user := range users {
		user, err = encryptUserInfo(user)
		if err != nil {
			return
		}
		users[i] = user
	}
	return nil
}

// 对用户的name、mobile、residentialAddressCode、residentialAddressDetail进行rsa加密
func encryptUserInfo(user epidemic.EpidemicUser) (result epidemic.EpidemicUser, err error) {
	result = user
	if result.Name != "" {
		if result.Name, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(user.Name)); err != nil {
			return
		}
	}
	if result.Mobile != "" {
		result.Mobile, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(user.Mobile))
		if err != nil {
			return
		}
	}
	if result.ResidentialAddressCode != "" {
		result.ResidentialAddressCode, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(user.ResidentialAddressCode))
		if err != nil {
			return
		}
	}
	if result.ResidentialAddressName != "" {
		result.ResidentialAddressName, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(user.ResidentialAddressName))
		if err != nil {
			return
		}
	}
	if result.ResidentialAddressDetail != "" {
		result.ResidentialAddressDetail, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(user.ResidentialAddressDetail))
		if err != nil {
			return
		}
	}
	return result, nil
}

// VerifyEpidemicUser 更新EpidemicUser记录
// Author [piexlmax](https://github.com/piexlmax)
func (epidemicUserService *EpidemicUserService) VerifyEpidemicUser(bean epidemicReq.EpidemicUserVerify) (err error) {
	ids := strings.Split(bean.UserIds, ",")
	err = global.GVA_DB.Where("id IN (?)", ids).Model(&epidemic.EpidemicUser{}).
		Updates(map[string]interface{}{
			"status":            bean.Status,
			"approved_by":       bean.ApprovedBy,
			"approval_date":     time.Now().Format("2006/01/02 15:04:05.000"),
			"approval_comments": bean.ApprovalComments}).Error
	return err
}

// 获取数据字典
func (epidemicUserService *EpidemicUserService) GetDict(info epidemicReq.DictSearch) (list []epidemic.EpidemicDictionaryDetail, err error) {
	// 创建db
	db := global.GVA_DB

	var dictStruct []epidemic.EpidemicDictionaryDetail
	if info.Key != "" {
		db = db.Where("`key`=?", info.Key)
	}
	err = db.Order("id asc").Find(&dictStruct).Error
	//db = db.Raw("SELECT * FROM sys_dictionary_details,( SELECT id FROM sys_dictionaries WHERE TYPE = ?" +
	//	" AND STATUS = 1 ) AS A WHERE sys_dictionary_id = A.id and STATUS=1", info.Type)
	//err = db.Scan(&dictStruct).Error
	return dictStruct, err
}

// GetValueByKeyAndName 数据字典-根据key和name获取value
func GetValueByKeyAndName(key, name string) (string, error) {
	if key == "" || name == "" {
		return "", errors.New("invalid paras")
	}
	db := global.GVA_DB
	value := ""
	if err := db.Table("epidemic_dictionary_detail").Where("`key`=? and name=?", key, name).Select("value").Find(&value).Error; err != nil {
		return "", err
	}
	return value, nil
}

// GetNameByKeyAndValue 数据字典-根据key和value获取name
func GetNameByKeyAndValue(key, value string) (string, error) {
	if key == "" || value == "" {
		return "", errors.New("invalid paras")
	}
	db := global.GVA_DB
	name := ""
	if err := db.Table("epidemic_dictionary_detail").Where("`key`=? and value=?", key, value).Select("name").Find(&name).Error; err != nil {
		return "", err
	}
	return name, nil
}

// Urge 催办
func (epidemicUserService *EpidemicUserService) Urge(bean epidemicReq.EpidemicUserUrge, operator epidemic.EpidemicUser) (err error) {
	switch bean.Type {
	case "investigation_user": // 每日健康登记
		return urgeTemperature(operator)
	case "investigation_detail": // 疫情筛查表填报登记
		return urgeEpidemicInvestigationForm(bean.Id)
	default:
		return errors.New("invalid paras")
	}
}

// 健康登记催办
func urgeTemperature(operator epidemic.EpidemicUser) error {
	// 获取目标人群
	var to []string
	db := global.GVA_DB.Model(&epidemic.EpidemicRelatedStaff{})
	nowDate := time.Now().Format("2006-01-02")
	if err := db.Select("mobile").
		Where("temperature_record not like ? and department in ?", "'%"+nowDate+"%'", prepare.Department(operator.Department)).
		Find(&to).Error; err != nil {
		return err
	}
	if len(to) == 0 {
		return errors.New("已全部上报，无需催办")
	}
	return msgsms.SendMsg(to, "4ed0761dfd6d4cd6b6a1a969ec8bfed3", "8819022138406", "")
}

// 疫情筛查表催办
func urgeEpidemicInvestigationForm(id int) error {
	if id == 0 {
		return errors.New("invalid id")
	}
	// 疫情排查表填报状态-未填
	status, err := GetValueByKeyAndName("investigation_write_status", "未填")
	if err != nil {
		return err
	}
	// 获取目标人群
	var info []epidemic.EpidemicInvestigationDetails
	db := global.GVA_DB.Model(&epidemic.EpidemicInvestigationDetails{})
	if err := db.Where("related_form_id=? and status=?", id, status).Find(&info).Error; err != nil {
		return err
	}
	if len(info) == 0 {
		return errors.New("已全部填报，无需催办")
	}
	var to []string
	for _, e := range info {
		to = append(to, e.Mobile)
	}
	return msgsms.SendMsg(to, "83bc70d8ec72437cbea8ea7aef4d1ae0", "8819022138406", "")
}

// 导出全部用户
func (epidemicUserService *EpidemicUserService) ExportAllUsers(user epidemic.EpidemicUser) (filename string, err error) {
	// 创建db
	db := global.GVA_DB.Model(&epidemic.EpidemicUser{})
	if user.Role != global.DICT_ROLES_SUPER {
		db = db.Where("company=? and department in ? and name !=''", user.Company, prepare.Department(user.Department))
	} else {
		db = db.Where("company=? and name !=''", user.Company)
	}
	// 获取信息
	var info []epidemic.EpidemicUser
	if err = db.Find(&info).Error; err != nil {
		return
	}

	return genExcelForExportUsers(info)
}

// GenExcel 生成excel
func genExcelForExportUsers(info []epidemic.EpidemicUser) (string, error) {
	f := excelize.NewFile()
	// Create a new sheet.
	sheet := "Sheet1"
	index := f.NewSheet(sheet)
	// Set value of a cell.
	if err := genExcelTitleForExportUsers(f, sheet); err != nil {
		return "", err
	}
	for i, e := range info {
		line := i + 2
		id := i + 1
		if err := genExcelLineForExportUsers(e, f, sheet, line, id); err != nil {
			return "", err
		}
	}
	// Set active sheet of the workbook.
	f.SetActiveSheet(index)
	// Save spreadsheet by the given path.
	nowDate := time.Now().Format("2006-01-02")
	fileName := fmt.Sprintf("%s%s%s%s", global.GVA_CONFIG.System.ExportFileDir, "用户信息", nowDate, ".xlsx")
	if err := f.SaveAs(fileName); err != nil {
		return "", err
	}
	return fileName, nil
}

// 生成标头
func genExcelTitleForExportUsers(f *excelize.File, sheet string) error {
	var title = []string{
		"序号",
		"状态",
		"姓名",
		"性别",
		"手机号",
		"出生日期",
		"公司",
		"部门",
		"编制",
		"常驻办公地",
		"居住地址",
		"已接种针次",
		"接种时间",
		"未接种完全原因",
		"角色",
		"审批意见",
		"标签",
	}
	for i := 0; i < len(title); i++ {
		axis := string(rune(65 + i))
		value := title[i]
		if err := f.SetCellValue(sheet, axis+strconv.Itoa(1), value); err != nil {
			return err
		}
	}
	return nil
}

func genExcelLineForExportUsers(info epidemic.EpidemicUser, f *excelize.File, sheet string, line, id int) error {
	i := 0
	if err := setCellValue(f, &i, id, sheet, line); err != nil {
		return err
	}
	// 状态
	status, _ := GetNameByKeyAndValue("approval_status", info.Status)
	if err := setCellValue(f, &i, status, sheet, line); err != nil {
		return err
	}
	// 姓名
	if err := setCellValue(f, &i, info.Name, sheet, line); err != nil {
		return err
	}
	// 性别
	sex, _ := GetNameByKeyAndValue("sex", info.Sex)
	if err := setCellValue(f, &i, sex, sheet, line); err != nil {
		return err
	}
	// 手机号
	if err := setCellValue(f, &i, info.Mobile, sheet, line); err != nil {
		return err
	}
	// 出生日期
	var birthday string
	if len(info.BirthDate) >= 10 {
		birthday = info.BirthDate[:10]
	}
	if err := setCellValue(f, &i, birthday, sheet, line); err != nil {
		return err
	}
	// 公司
	Company, _ := GetNameByKeyAndValue("company", info.Company)
	if err := setCellValue(f, &i, Company, sheet, line); err != nil {
		return err
	}
	// 部门
	departmentSlice := strings.Split(info.Department, ",")
	Department := ""
	for i, e := range departmentSlice {
		tmp, _ := GetNameByKeyAndValue("department", e)
		Department += tmp
		if i+1 != len(departmentSlice) {
			Department += ","
		}
	}
	if err := setCellValue(f, &i, Department, sheet, line); err != nil {
		return err
	}
	// 编制
	Organization, _ := GetNameByKeyAndValue("organization", info.Organization)
	if err := setCellValue(f, &i, Organization, sheet, line); err != nil {
		return err
	}
	// 常驻办公地
	Location, _ := GetNameByKeyAndValue("workcity", info.Location)
	if err := setCellValue(f, &i, Location, sheet, line); err != nil {
		return err
	}

	// 居住地址
	if err := setCellValue(f, &i, info.ResidentialAddressName+info.ResidentialAddressDetail, sheet, line); err != nil {
		return err
	}

	// 疫苗接种记录
	vaccinationRecord, _ := GetNameByKeyAndValue("vaccination_ecord", info.VaccinationRecord)
	if err := setCellValue(f, &i, vaccinationRecord, sheet, line); err != nil {
		return err
	}
	// 疫苗接种时间
	if err := setCellValue(f, &i, info.VaccinationTime, sheet, line); err != nil {
		return err
	}
	// 未接种完全原因
	reasonForNonVaccination, _ := GetNameByKeyAndValue("reason_for_non_vaccination", info.ReasonForNonVaccination)
	if err := setCellValue(f, &i, reasonForNonVaccination, sheet, line); err != nil {
		return err
	}
	// 角色
	role, _ := GetNameByKeyAndValue("roles", info.Role)
	if err := setCellValue(f, &i, role, sheet, line); err != nil {
		return err
	}
	// 审批意见
	if err := setCellValue(f, &i, info.ApprovalComments, sheet, line); err != nil {
		return err
	}
	// 标签
	label, _ := GetNameByKeyAndValue("label", info.Label)
	if err := setCellValue(f, &i, label, sheet, line); err != nil {
		return err
	}
	return nil
}

// 导出全部用户
func (epidemicUserService *EpidemicUserService) GetAllManagersMobile() (list []string, err error) {
	// 创建db
	db := global.GVA_DB.Model(&epidemic.EpidemicUser{})
	// 获取信息
	if err = db.Where("role in ('1', '3')").
		Select("mobile").
		Find(&list).Error; err != nil {
		return
	}
	return
}

func (epidemicUserService *EpidemicUserService) GetUserByMobile(mobile string) (user epidemic.EpidemicUser, err error) {
	db := global.GVA_DB
	if err = db.Where("mobile=? ", mobile).
		Find(&user).Error; err != nil {
		return
	}
	return
}
